home *** CD-ROM | disk | FTP | other *** search
- ;;!emacs
- ;;
- ;; FILE: kfill.el
- ;; SUMMARY: Fill and justify koutline cells (adapted from Kyle Jones' filladapt).
- ;; USAGE: GNU Emacs Lisp Library
- ;; KEYWORDS: outlines, wp
- ;;
- ;; AUTHOR: Bob Weiner
- ;; ORIG-DATE: 23-Jan-94
- ;; LAST-MOD: 17-Apr-95 at 11:53:55 by Bob Weiner
- ;;
- ;; This file is part of Hyperbole.
- ;; Available for use and distribution under the same terms as GNU Emacs.
- ;;
- ;; Copyright (C) 1994-1995, Free Software Foundation, Inc.
- ;; Developed with support from Motorola Inc.
- ;;
- ;; DESCRIPTION:
- ;;
- ;; Based upon LCD Archive Entry:
- ;; filladapt|Kyle E. Jones|kyle@crystal.wonderworks.com|
- ;; Enhance Emacs fill commands to dynamically determine the fill prefix.|
- ;; $Date: 1993/07/20 19:44:39 $|$Revision: 1.2 $|~/packages/filladapt.el.Z|
- ;; Copyright (C) 1989 Kyle E. Jones
- ;;
- ;; This package provides no muss, no fuss word wrapping and filling of
- ;; paragraphs with hanging indents, included text from news and mail
- ;; messages, and Lisp, C++, PostScript or shell comments. It is table
- ;; driven, so you can add your own favorites.
- ;;
- ;; These functions enhance the default behavior of the Emacs'
- ;; auto-fill-mode and the command fill-paragraph. The chief improvement
- ;; is that the beginning of a line to be filled is examined and
- ;; appropriate values for fill-prefix, and the various paragraph-*
- ;; variables are constructed and used during fills. This occurs only if
- ;; the fill prefix is not already non-nil.
- ;;
- ;; The net result of this is that blurbs of text that are offset from
- ;; left margin by asterisks, dashes, and/or spaces, numbered examples,
- ;; included text from USENET news articles, etc. are generally filled
- ;; correctly with no fuss.
- ;;
- ;; DESCRIP-END.
- ;;
- ;; MODS:
- ;;
- ;; Bob Weiner, Motorola Inc., 8/11/93
- ;; Added filladapt-hanging-p which uses current settings of hanging indent
- ;; pattern (see filladapt-hanging-expression) to test if at a hanging
- ;; indent. Changed filladapt-hanging-list to use this function.
- ;; Bob Weiner, Motorola Inc., 1/27/94
- ;; Added removal of previous fill prefix before filling through
- ;; 'filladapt-replace-string' function.
- ;;
- ;; 20 July 1993: Patches to work with FSF GNU Emacs 19
- ;; Paul D. Smith <psmith@wellfleet.com>
- ;; END-MODS.
-
-
- ;;; ************************************************************************
- ;;; Public variables
- ;;; ************************************************************************
-
- (defvar filladapt-function-table
- (list (cons 'fill-paragraph (symbol-function 'fill-paragraph))
- (cons 'do-auto-fill (symbol-function 'do-auto-fill)))
- "Table containing the old function definitions that filladapt usurps.")
-
- ;;; Prevent any old version of this variable from being used since it will
- ;;; not work properly with koutlines.
- (makunbound 'filladapt-prefix-table)
- (defvar filladapt-prefix-table
- '(
- ;; Lists with hanging indents, e.g.
- ;; 1. xxxxx or 1) xxxxx etc.
- ;; xxxxx xxx
- ;;
- ;; Be sure pattern does not match to: (last word in parens starts
- ;; newline)
- (" *(?\\([0-9][0-9a-z.]*\\|[a-z][0-9a-z.]\\)) +" . filladapt-hanging-list)
- (" *\\([0-9]+[a-z.]+[0-9a-z.]*\\|[0-9]+\\|[a-z]\\)\\([.>] +\\| +\\)"
- . filladapt-hanging-list)
- ;; Included text in news or mail replies
- ("[ \t]*\\(>+ *\\)+" . filladapt-normal-included-text)
- ;; Included text generated by SUPERCITE. We can't hope to match all
- ;; the possible variations, your mileage may vary.
- ("[^'`\"< \t]*> *" . filladapt-supercite-included-text)
- ;; Lisp comments
- ("[ \t]*\\(;+[ \t]*\\)+" . filladapt-lisp-comment)
- ;; UNIX shell comments
- ("[ \t]*\\(#+[ \t]*\\)+" . filladapt-sh-comment)
- ;; Postscript comments
- ("[ \t]*\\(%+[ \t]*\\)+" . filladapt-postscript-comment)
- ;; C++ comments
- ("[ \t]*//[/ \t]*" . filladapt-c++-comment)
- ("[?!~*+ -]+ " . filladapt-hanging-list)
- ;; This keeps normal paragraphs from interacting unpleasantly with
- ;; the types given above.
- ("[^ \t/#%?!~*+-]" . filladapt-normal)
- )
- "Value is an alist of the form
-
- ((REGXP . FUNCTION) ...)
-
- When fill-paragraph or do-auto-fill is called, the REGEXP of each alist
- element is compared with the beginning of the current line. If a match
- is found the corresponding FUNCTION is called. FUNCTION is called with
- one argument, which is non-nil when invoked on the behalf of
- fill-paragraph, nil for do-auto-fill. It is the job of FUNCTION to set
- the values of the paragraph-* variables (or set a clipping region, if
- paragraph-start and paragraph-separate cannot be made discerning enough)
- so that fill-paragraph and do-auto-fill work correctly in various
- contexts.")
-
- ;;; ************************************************************************
- ;;; Public functions
- ;;; ************************************************************************
-
- (defun do-auto-fill ()
- (save-restriction
- (if (null fill-prefix)
- (let (fill-prefix)
- (filladapt-adapt nil)
- (filladapt-funcall 'do-auto-fill))
- (filladapt-funcall 'do-auto-fill))))
-
- (defun fill-paragraph (arg &optional skip-prefix-remove)
- "Fill paragraph at or after point. Prefix ARG means justify as well."
- (interactive "*P")
- (or skip-prefix-remove (filladapt-remove-paragraph-prefix))
- (save-restriction
- (catch 'done
- (if (null fill-prefix)
- (let (paragraph-ignore-fill-prefix
- fill-prefix
- (paragraph-start paragraph-start)
- (paragraph-separate paragraph-separate))
- (if (filladapt-adapt t)
- (throw 'done (filladapt-funcall 'fill-paragraph arg)))))
- ;; Filladapt-adapt failed or fill-prefix is set, so do a basic
- ;; paragraph fill as adapted from par-align.el.
- (filladapt-fill-paragraph arg skip-prefix-remove))))
-
- ;;;
- ;;; Redefine this function so that it sets 'fill-prefix-prev' also.
- ;;;
- (defun set-fill-prefix (&optional turn-off)
- "Set the fill-prefix to the current line up to point.
- Also sets fill-prefix-prev to previous value of fill-prefix.
- Filling expects lines to start with the fill prefix and reinserts the fill
- prefix in each resulting line."
- (interactive)
- (setq fill-prefix-prev fill-prefix
- fill-prefix (if turn-off
- nil
- (buffer-substring
- (save-excursion (beginning-of-line) (point))
- (point))))
- (if (equal fill-prefix-prev "")
- (setq fill-prefix-prev nil))
- (if (equal fill-prefix "")
- (setq fill-prefix nil))
- (if fill-prefix
- (message "fill-prefix: \"%s\"" fill-prefix)
- (message "fill-prefix cancelled")))
-
- ;;; ************************************************************************
- ;;; Private functions
- ;;; ************************************************************************
-
- (defun filladapt-adapt (paragraph)
- (let ((table filladapt-prefix-table)
- case-fold-search
- success )
- (save-excursion
- (beginning-of-line)
- (while table
- (if (not (looking-at (car (car table))))
- (setq table (cdr table))
- (funcall (cdr (car table)) paragraph)
- (setq success t table nil))))
- success ))
-
- (defun filladapt-c++-comment (paragraph)
- (setq fill-prefix (buffer-substring (match-beginning 0) (match-end 0)))
- (if paragraph
- (setq paragraph-separate "^[^ \t/]")))
-
- (defun filladapt-fill-paragraph (justify-flag &optional leave-prefix)
- (save-excursion
- (end-of-line)
- ;; Backward to para begin
- (re-search-backward (concat "\\`\\|" paragraph-separate))
- (forward-line 1)
- (let ((region-start (point)))
- (forward-line -1)
- (let ((from (point)))
- (forward-paragraph)
- ;; Forward to real paragraph end
- (re-search-forward (concat "\\'\\|" paragraph-separate))
- (or (= (point) (point-max)) (beginning-of-line))
- (or leave-prefix
- (filladapt-replace-string
- (or fill-prefix fill-prefix-prev)
- "" nil region-start (point)))
- (fill-region-as-paragraph from (point) justify-flag)))))
-
- (defun filladapt-funcall (function &rest args)
- (apply (cdr (assq function filladapt-function-table)) args))
-
- (defun filladapt-hanging-list (paragraph)
- (let (prefix match beg end)
- (setq prefix (make-string (- (match-end 0) (match-beginning 0)) ?\ ))
- (if paragraph
- (progn
- (setq match (buffer-substring (match-beginning 0) (match-end 0)))
- (if (string-match "^ +$" match)
- (save-excursion
- (while (and (not (bobp)) (looking-at prefix))
- (forward-line -1))
-
- (cond ((filladapt-hanging-p)
- (setq beg (point)))
- (t (setq beg (progn (forward-line 1) (point))))))
- (setq beg (point)))
- (save-excursion
- (forward-line)
- (while (and (looking-at prefix)
- (not (equal (char-after (match-end 0)) ?\ )))
- (forward-line))
- (setq end (point)))
- (narrow-to-region beg end)))
- (setq fill-prefix prefix)))
-
- (defun filladapt-hanging-p ()
- "Return non-nil iff point is in front of a hanging list."
- (eval filladapt-hanging-expression))
-
- (defun filladapt-lisp-comment (paragraph)
- (setq fill-prefix (buffer-substring (match-beginning 0) (match-end 0)))
- (if paragraph
- (setq paragraph-separate
- (concat "^" fill-prefix " *;\\|^"
- (filladapt-negate-string fill-prefix)))))
-
- (defun filladapt-negate-string (string)
- (let ((len (length string))
- (i 0) string-list)
- (setq string-list (cons "\\(" nil))
- (while (< i len)
- (setq string-list
- (cons (if (= i (1- len)) "" "\\|")
- (cons "]"
- (cons (substring string i (1+ i))
- (cons "[^"
- (cons (regexp-quote (substring string 0 i))
- string-list)))))
- i (1+ i)))
- (setq string-list (cons "\\)" string-list))
- (apply 'concat (nreverse string-list))))
-
- (defun filladapt-normal (paragraph)
- (if paragraph
- (setq paragraph-separate
- (concat paragraph-separate "\\|^[ \t/#%?!~*+-]"))))
-
- (defun filladapt-normal-included-text (paragraph)
- (setq fill-prefix (buffer-substring (match-beginning 0) (match-end 0)))
- (if paragraph
- (setq paragraph-separate
- (concat "^" fill-prefix " *>\\|^"
- (filladapt-negate-string fill-prefix)))))
-
- (defun filladapt-postscript-comment (paragraph)
- (setq fill-prefix (buffer-substring (match-beginning 0) (match-end 0)))
- (if paragraph
- (setq paragraph-separate
- (concat "^" fill-prefix " *%\\|^"
- (filladapt-negate-string fill-prefix)))))
-
- (defun filladapt-remove-paragraph-prefix (&optional indent-str)
- "Remove fill prefix from current paragraph."
- (save-excursion
- (end-of-line)
- ;; Backward to para begin
- (re-search-backward (concat "\\`\\|" paragraph-separate))
- (forward-line 1)
- (let ((region-start (point)))
- (forward-line -1)
- (forward-paragraph)
- ;; Forward to real paragraph end
- (re-search-forward (concat "\\'\\|" paragraph-separate))
- (or (= (point) (point-max)) (beginning-of-line))
- (filladapt-replace-string (or fill-prefix fill-prefix-prev)
- (if (eq major-mode 'kotl-mode)
- (or indent-str
- (make-string (kcell-view:indent) ? ))
- "")
- nil region-start (point)))))
-
- (defun filladapt-replace-string (fill-str-prev fill-str &optional suffix start end)
- "Replace whitespace separated FILL-STR-PREV with FILL-STR.
- Optional SUFFIX non-nil means replace at ends of lines, default is beginnings.
- Optional arguments START and END specify the replace region, default is the
- current region."
- (if fill-str-prev
- (progn (if start
- (let ((s (min start end)))
- (setq end (max start end)
- start s))
- (setq start (region-beginning)
- end (region-end)))
- (if (not fill-str) (setq fill-str ""))
- (save-excursion
- (save-restriction
- (narrow-to-region start end)
- (goto-char (point-min))
- (let ((prefix
- (concat
- (if suffix nil "^")
- "[ \t]*"
- (regexp-quote
- ;; Get non-whitespace separated fill-str-prev
- (substring
- fill-str-prev
- (or (string-match "[^ \t]" fill-str-prev) 0)
- (if (string-match
- "[ \t]*\\(.*[^ \t]\\)[ \t]*$"
- fill-str-prev)
- (match-end 1))))
- "[ \t]*"
- (if suffix "$"))))
- (while (re-search-forward prefix nil t)
- (replace-match fill-str nil t))))))))
-
- (defun filladapt-sh-comment (paragraph)
- (setq fill-prefix (buffer-substring (match-beginning 0) (match-end 0)))
- (if paragraph
- (setq paragraph-separate
- (concat "^" fill-prefix " *#\\|^"
- (filladapt-negate-string fill-prefix)))))
-
- (defun filladapt-supercite-included-text (paragraph)
- (setq fill-prefix (buffer-substring (match-beginning 0) (match-end 0)))
- (if paragraph
- (setq paragraph-separate
- (concat "^" (filladapt-negate-string fill-prefix)))))
-
- ;;; ************************************************************************
- ;;; Private variables
- ;;; ************************************************************************
-
- (defconst filladapt-hanging-expression
- (cons 'or
- (delq nil (mapcar (function
- (lambda (pattern-type)
- (if (eq (cdr pattern-type) 'filladapt-hanging-list)
- (list 'looking-at (car pattern-type)))))
- filladapt-prefix-table)))
- "Conditional expression used to test for hanging indented lists.")
-
- (defvar fill-prefix-prev nil
- "Prior string inserted at front of new line during filling, or nil for none.
- Setting this variable automatically makes it local to the current buffer.")
- (make-variable-buffer-local 'fill-prefix-prev)
-
-
- (provide 'kfill)
- (provide 'filladapt)
-